use rodio::{Decoder, OutputStream, Sink};
use std::fs::File;
use std::io::BufReader;
use std::path::Path;
use std::sync::Mutex;
use log::{error, info, warn};

/// 音频管理器
pub struct AudioManager {
    _stream: OutputStream,
    sink: Sink,
}

impl AudioManager {
    /// 创建新的音频管理器实例
    pub fn new() -> Result<Self, Box<dyn std::error::Error>> {
        let (_stream, stream_handle) = OutputStream::try_default()?;
        let sink = Sink::try_new(&stream_handle)?;
        
        Ok(AudioManager {
            _stream,
            sink,
        })
    }

    /// 播放指定的音频文件
    pub fn play_audio(&self, file_path: &str) -> Result<(), Box<dyn std::error::Error>> {
        if !Path::new(file_path).exists() {
            let error_msg = format!("Audio file not found: {}", file_path);
            error!("{}", error_msg);
            return Err(error_msg.into());
        }

        let file = File::open(file_path)?;
        let buf_reader = BufReader::new(file);
        let source = Decoder::new(buf_reader)?;
        
        self.sink.append(source);
        info!("Playing audio file: {}", file_path);
        
        Ok(())
    }

    /// 播放错误提示音（使用longOnce.wav）
    pub fn play_error_sound(&self) {
        let audio_path = "public/video/longOnce.wav";
        
        if let Err(e) = self.play_audio(audio_path) {
            warn!("Failed to play error sound: {}", e);
        }
    }

    /// 停止当前播放的音频
    pub fn stop(&self) {
        self.sink.stop();
        info!("Audio playback stopped");
    }

    /// 暂停音频播放
    pub fn pause(&self) {
        self.sink.pause();
        info!("Audio playback paused");
    }

    /// 恢复音频播放
    pub fn resume(&self) {
        self.sink.play();
        info!("Audio playback resumed");
    }

    /// 设置音量 (0.0 - 1.0)
    pub fn set_volume(&self, volume: f32) {
        let clamped_volume = volume.clamp(0.0, 1.0);
        self.sink.set_volume(clamped_volume);
        info!("Audio volume set to: {}", clamped_volume);
    }

    /// 检查是否正在播放
    pub fn is_playing(&self) -> bool {
        !self.sink.empty()
    }
}

/// 全局音量设置
lazy_static::lazy_static! {
    static ref GLOBAL_VOLUME: Mutex<f32> = Mutex::new(1.0);
}

/// 获取音频文件的完整路径
/// 
/// 支持以下路径查找顺序：
/// 1. 开发环境：public/video/*.wav
/// 2. 生产环境（打包后）：_up_/public/video/*.wav
/// 3. 备用路径：exe目录下的相对路径
fn get_audio_path(relative_path: &str) -> Result<std::path::PathBuf, Box<dyn std::error::Error>> {
    let exe_dir = std::env::current_exe()?
        .parent()
        .ok_or("Failed to get executable directory")?
        .to_path_buf();
    
    // 尝试多个可能的路径
    let possible_paths = vec![
        // 1. 开发环境：当前工作目录下的 public/video/
        std::env::current_dir()?.join(relative_path),
        
        // 2. 生产环境：exe目录下的 _up_/public/video/
        exe_dir.join("_up_").join(relative_path),
        
        // 3. 生产环境备用：exe目录下的 public/video/
        exe_dir.join(relative_path),
        
        // 4. 项目根目录（开发环境备用）
        std::env::current_dir()?.parent()
            .ok_or("No parent dir")?
            .join(relative_path),
    ];
    
    for path in &possible_paths {
        if path.exists() {
            info!("Found audio file at: {:?}", path);
            return Ok(path.clone());
        }
    }
    
    // 记录所有尝试过的路径，方便调试
    warn!("Audio file not found. Tried paths:");
    for (i, path) in possible_paths.iter().enumerate() {
        warn!("  {}. {:?}", i + 1, path);
    }
    
    Err(format!("Audio file not found: {}", relative_path).into())
}

/// 播放音频文件的内部实现
fn play_audio_internal(file_path: &str) -> Result<(), Box<dyn std::error::Error>> {
    let audio_path = get_audio_path(file_path)?;
    
    if !audio_path.exists() {
        let error_msg = format!("Audio file not found: {:?}", audio_path);
        error!("{}", error_msg);
        return Err(error_msg.into());
    }

    let file = File::open(&audio_path)?;
    let buf_reader = BufReader::new(file);
    let source = Decoder::new(buf_reader)?;
    
    // 获取音量
    let volume = *GLOBAL_VOLUME.lock().unwrap();
    
    info!("Playing audio file: {:?}", audio_path);
    
    // 在新线程中创建音频流和播放，避免Send问题
    std::thread::spawn(move || {
        match OutputStream::try_default() {
            Ok((_stream, stream_handle)) => {
                match Sink::try_new(&stream_handle) {
                    Ok(sink) => {
                        sink.set_volume(volume);
                        sink.append(source);
                        sink.sleep_until_end();
                        // _stream 和 sink 在这里自动drop
                    }
                    Err(e) => error!("Failed to create audio sink: {}", e),
                }
            }
            Err(e) => error!("Failed to create audio output stream: {}", e),
        }
    });
    
    Ok(())
}

/// 播放错误提示音的便捷函数
pub fn play_error_notification() {
    let audio_path = "public/video/longOnce.wav";
    if let Err(e) = play_audio_internal(audio_path) {
        warn!("Failed to play error notification: {}", e);
    }
}

/// 播放指定音频文件的便捷函数
pub fn play_audio_file(file_path: &str) -> Result<(), Box<dyn std::error::Error>> {
    play_audio_internal(file_path)
}

/// 设置全局音量的便捷函数
pub fn set_global_volume(volume: f32) {
    let clamped_volume = volume.clamp(0.0, 1.0);
    let mut global_volume = GLOBAL_VOLUME.lock().unwrap();
    *global_volume = clamped_volume;
    info!("Global audio volume set to: {}", clamped_volume);
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_audio_manager_creation() {
        let manager = AudioManager::new();
        assert!(manager.is_ok());
    }

    #[test]
    fn test_play_nonexistent_file() {
        if let Ok(manager) = AudioManager::new() {
            let result = manager.play_audio("nonexistent.wav");
            assert!(result.is_err());
        }
    }

    #[test]
    fn test_volume_clamping() {
        if let Ok(manager) = AudioManager::new() {
            // 测试音量范围限制
            manager.set_volume(-1.0); // 应该被限制为0.0
            manager.set_volume(2.0);  // 应该被限制为1.0
            manager.set_volume(0.5);  // 正常值
        }
    }
}
